﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using LotteryVote.Data;
using LotteryVote.Entity;
using LotteryVote.Utility;
using LotteryVote.Logic.Exceptions;

namespace LotteryVote.Logic
{
    public class LotteryResultFacade
    {
        private LotteryResultDataAccess _daLotteryResult;
        internal LotteryResultDataAccess DaLotteryResult
        {
            get
            {
                if (_daLotteryResult == null)
                    _daLotteryResult = new LotteryResultDataAccess();
                return _daLotteryResult;
            }
            set
            {
                _daLotteryResult = value;
            }
        }

        private NumLengthDataAccess _daNumLen;
        internal NumLengthDataAccess DaNumLength
        {
            get
            {
                if (_daNumLen == null)
                    _daNumLen = new NumLengthDataAccess();
                return _daNumLen;
            }
            set
            {
                _daNumLen = value;
            }
        }


        public IEnumerable<LotteryResult> GetLotteryResultByDate(DateTime date)
        {
            var ds = DaLotteryResult.GetResultByDate(date);
            var result =
                from x in ds.Tables[0].AsEnumerable()
                group x by x.Field<int>(LotteryPeriod.COMPANYID) into gp
                select new LotteryResult(DaLotteryResult.ToCompany(gp), DaLotteryResult.ToRecordList(gp), date);
            return result.OrderByDescending(it => it.Records.Count);
        }

        /// <summary>
        /// 指定公司添加开奖号码
        /// </summary>
        /// <param name="companyId">The company id.</param>
        /// <param name="num">The num.</param>
        [Obsolete("该方法已弃用，请使用AddLotteryResult")]
        public void CompanyAddRecord(int companyId, string num)
        {
            var company = TodayLotteryCompany.Instance.GetTodayCompany().Find(it => it.CompanyId == companyId);
            CheckRecord(num, company);
            var period = DaLotteryResult.GetPeriod(company, DateTime.Today);
            if (period == null)
            {
                period = new LotteryPeriod
                {
                    Company = company
                };
                DaLotteryResult.InsertPeriod(period);
            }
            var record = new LotteryRecord
            {
                PeriodId = period.PeriodId,
                Value = num
            };
            DaLotteryResult.InsertRecord(record);
        }

        public void AddLotteryResult(int companyId, IList<LotteryRecord> recordList)
        {
            var company = TodayLotteryCompany.Instance.GetTodayCompany().Find(it => it.CompanyId == companyId);

            recordList.ForEach(it =>
            {
                if (!it.Value.IsNum())
                    throw new PromptException("Confirmation number for the digital!");
            });

            var numLenSupport = DaNumLength.GetSupportNumLengthByType(company.CompanyType);
            foreach (var support in numLenSupport)
            {
                var numLenCount = recordList.Where(it => it.Value.Length == support.Length.Length).Count();
                if (numLenCount != support.Count)
                    throw new PromptException("Please confirm the accuracy of the numbers!");
            }

            var period = DaLotteryResult.GetPeriod(company, DateTime.Today);
            if (period == null)
            {
                period = new LotteryPeriod
                {
                    Company = company
                };
                DaLotteryResult.InsertPeriod(period);
            }
            DaLotteryResult.ExecuteWithTransaction(() =>
            {
                DaLotteryResult.DeleteRecord(period);
                recordList.ForEach(it =>
                {
                    it.PeriodId = period.PeriodId;
                    DaLotteryResult.InsertRecord(it);
                });
            });
        }

        /// <summary>
        /// 指定公司今日是否还可以输入开奖号码（未完全开完）.
        /// </summary>
        /// <param name="companyId">The company id.</param>
        /// <returns>
        ///   <c>true</c> if this instance [can input record value] the specified company id; otherwise, <c>false</c>.
        /// </returns>
        public bool CanInputRecordValue(int companyId)
        {
            var company = TodayLotteryCompany.Instance.GetTodayCompany().Find(it => it.CompanyId == companyId);
            var numLenSupport = DaNumLength.GetSupportNumLengthByType(company.CompanyType);
            var records = GetTodayRecordByCompany(companyId);
            return records.Count < numLenSupport.Sum(it => it.Count);
        }

        /// <summary>
        /// 获取今日指定公司的开奖记录.
        /// </summary>
        /// <param name="companyId">The company id.</param>
        /// <returns></returns>
        public IList<LotteryRecord> GetTodayRecordByCompany(int companyId)
        {
            var company = TodayLotteryCompany.Instance.GetTodayCompany().Find(it => it.CompanyId == companyId);
            return DaLotteryResult.ListRecord(company, DateTime.Today);
        }

        private void CheckRecord(string num, LotteryCompany company)
        {
            var numLenSupport = DaNumLength.GetSupportNumLengthByType(company.CompanyType);
            var records = GetTodayRecordByCompany(company.CompanyId);
            int numLenCount = records.Where(it => it.Value.Length == num.Length).Count();
            int supportNumLenCount = numLenSupport.Where(it => it.Length.Length == num.Length).First().Count;
            if (numLenCount >= supportNumLenCount)
            {
                LogConsole.Error(string.Format("CompanyId：{0} 长度为{1}的开奖结果已达到{2}!", company.CompanyId, num.Length, supportNumLenCount));
                throw new ApplicationException("已超出指定长度的开奖结果！");
            }

            numLenCount = records.Where(it => it.Value.Length == num.Length - 1).Count();
            supportNumLenCount = (numLenSupport.Where(it => it.Length.Length == num.Length - 1).FirstOrDefault() ?? CompanyTypeSupportNumLen.Empty).Count;
            if (numLenCount < supportNumLenCount)
            {
                LogConsole.Error(string.Format("CompanyId：{0} 长度为{1}的开奖结果未达到{2}!", company.CompanyId, num.Length - 1, supportNumLenCount));
                throw new ApplicationException("还未达到指定长度的开奖结果！");
            }
        }
    }
}
